import { OPCUAServer, Variant, DataType } from 'node-opcua'

async function startServer(): Promise<void> {
  const server = new OPCUAServer({
    port: 4840,
    resourcePath: '/UA/MyServer',
    buildInfo: {
      productName: 'MySampleServer',
      buildNumber: '1',
      buildDate: new Date()
    }
  })

  await server.initialize()

  const addressSpace = server.engine.addressSpace!
  const namespace = addressSpace.getOwnNamespace()

  const device = namespace.addObject({
    organizedBy: addressSpace.rootFolder.objects,
    browseName: 'MyDevice'
  })

  // 定义变量初始值
  let temperature = 20
  let angle = 90
  let vacuum = 101325
  let magnetism = 0.5

  // 添加变量
  namespace.addVariable({
    componentOf: device,
    browseName: 'Temperature',
    nodeId: 'ns=1;s=Temperature',
    dataType: 'Double',
    value: {
      get: () => new Variant({ dataType: DataType.Double, value: temperature })
    }
  })

  namespace.addVariable({
    componentOf: device,
    browseName: 'Angle',
    nodeId: 'ns=1;s=Angle',
    dataType: 'Double',
    value: {
      get: () => new Variant({ dataType: DataType.Double, value: angle })
    }
  })

  namespace.addVariable({
    componentOf: device,
    browseName: 'Vacuum',
    nodeId: 'ns=1;s=Vacuum',
    dataType: 'Double',
    value: {
      get: () => new Variant({ dataType: DataType.Double, value: vacuum })
    }
  })

  namespace.addVariable({
    componentOf: device,
    browseName: 'Magnetism',
    nodeId: 'ns=1;s=Magnetism',
    dataType: 'Double',
    value: {
      get: () => new Variant({ dataType: DataType.Double, value: magnetism })
    }
  })

  await server.start()
  console.log(
    'Server is now listening on',
    server.endpoints[0].endpointDescriptions()[0].endpointUrl
  )

  // Optional: simulate value change
  setInterval(() => {
    temperature += (Math.random() - 0.5) * 0.5
    angle += (Math.random() - 0.5) * 2
    vacuum += (Math.random() - 0.5) * 10
    magnetism += (Math.random() - 0.5) * 0.01
  }, 1000)
}

startServer().catch(console.error)
